package com.bootdo.front.controller;

import cn.hutool.core.lang.Validator;
import com.bootdo.common.annotation.Log;
import com.bootdo.common.config.Constant;
import com.bootdo.common.controller.BaseController;
import com.bootdo.common.pojo.UserReq;
import com.bootdo.common.shiro.MobileToken;
import com.bootdo.common.utils.*;
import com.bootdo.system.domain.UserDO;
import com.bootdo.system.service.LoginService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * 前台登陆控制器
 *
 * @author zhouxm
 */
@Controller
@RequestMapping("/front")
@Slf4j
public class FrontLoginController extends BaseController {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private LoginService loginService;

    @Log("前台发送验证码")
    @PostMapping("/sendVerifyCode")
    @ResponseBody
    public R sendVerifyCode(String mobile) {
        if (!(Validator.isMobile(mobile))) {
            return R.error("手机号码格式错误，请重新填写！");
        }
        R r = new R();
        try {
            r = loginService.sendVerifyCode(mobile);
        } catch (Exception e) {
            log.error("短信验证码发送异常:", e);
            return R.error("短信发送失败");
        }
        return r;
    }

    private R checkCode(String mobile, String code) throws Exception {
        String redisCode = (String) redisUtils.get(mobile);
        if (StringUtils.isEmpty(redisCode)) {
            return R.error("验证码无效或已过期，请重新发送！");
        }
        if (loginService.checkCodeUsed(mobile, code)) {
            return R.error("验证码已使用，请重新发送！");
        }
        return R.ok();
    }

    @Log("前台手机号加验证码登陆")
    @PostMapping("/mobileLogin")
    @ResponseBody
    public R mobileLogin(String mobile, String code) {
        // 获取redis中的验证码
        String redisCode = (String) redisUtils.get(mobile);
        try {
            R res = checkCode(mobile, code);
            if (Objects.equals(res.get("code"), Constant.ERROR_CODE)) {
                return res;
            }
            if (Objects.equals(redisCode, code)) {
                MobileToken mobileToken = new MobileToken(mobile);
                Subject subject = SecurityUtils.getSubject();
                subject.login(mobileToken);
                UserDO userDO = (UserDO) subject.getPrincipal();
                loginService.updateCodeStatus(mobile, code);
                return R.ok(userDO);
            }
        } catch (Exception e) {
            log.error("登陆失败：", e);
            return R.error("登陆失败！");
        }
        return R.error("验证码错误！");
    }

    /**
     * 生成验证码
     */
    @GetMapping(value = "/getVerify")
    public void getVerify(HttpServletRequest request, HttpServletResponse response) {
        try {
            //设置相应类型,告诉浏览器输出的内容为图片
            response.setContentType("image/jpeg");
            //设置响应头信息，告诉浏览器不要缓存此内容
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expire", 0);
            RandomValidateCodeUtil randomValidateCode = new RandomValidateCodeUtil();
            //输出验证码图片方法
            randomValidateCode.getRandcode(request, response);
        } catch (Exception e) {
            log.error("获取验证码失败>>>> ", e);
        }
    }

    @Log("前台用户名密码登陆")
    @PostMapping("/usernameLogin")
    @ResponseBody
    public R usernameLogin(UserReq req, HttpServletRequest request) {
        String username = req.getUsername();
        String password = req.getPassword();
        String verify = req.getVerify();
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            return R.error("用户名和密码不能为空！");
        }
        //从session中获取随机数
        String random = (String) request.getSession().getAttribute(RandomValidateCodeUtil.RANDOMCODEKEY);
        if (StringUtils.isBlank(verify)) {
            return R.error("请输入验证码");
        }
        if (!(Objects.equals(verify, random))) {
            return R.error("请输入正确的验证码");
        }
        password = MD5Utils.encrypt(username, password);
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        Subject subject = SecurityUtils.getSubject();
        subject.login(token);
        UserDO userDO = (UserDO) subject.getPrincipal();
        return R.ok(userDO);
    }

    /*@Log("注册")
    @PostMapping("/register")
    @ResponseBody
    public R register(UserReq req) {
        String password = Constant.PASSWORD;
        req.setPassword(password);
        String username = req.getMobile();
        req.setUsername(username);
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            return R.error("用户名和密码不能为空！");
        }
        req.setPassword(MD5Utils.encrypt(username, password));
        if (!(Validator.isMobile(req.getMobile()))) {
            return R.error("手机号码格式错误，请重新填写！");
        }
        try {
            *//*R result = checkCode(req.getMobile(), req.getCode());
            if (Objects.equals(result.get(R.CODE_KEY), Constant.ERROR_CODE)) {
                return result;
            }*//*
            int res = loginService.register(req);
            if (res == -1) {
                return R.error("该手机号已被注册，请重新填写！");
            }
            if (res == 0) {
                return R.error("服务器繁忙，请稍后再试！");
            }
        } catch (Exception e) {
            log.error("服务器内部错误：", e);
            return R.error("服务器繁忙，请稍后再试！");
        }
        return R.ok();
    }*/
}
